/*
 * DataStream.h
 *
 *  Created on: Mar 27, 2013
 *      Author: root
 */

#ifndef DATASTREAM_H_
#define DATASTREAM_H_

#include "http.h"
#include "chunk_buf.h"
#include "DataClip.h"

#define AV_CHUNK_CACH_COUNT 20
#define AV_CHUNK_BUF_SIZE  0xffff * 2
#define MAX_DATA_STREAM_COUNT 1000

/*data stream status*/
enum stream_status{DS_CLOSE,DS_ACTIVE,DS_PAUSE};
/*
*av chunk data define
*/
struct data_stream
{
	uint16_t streamid;/*stream id :data stream ID*/
	uint8_t  fmt;/*data chunk fmt*/
	uint64_t current_index;/*current max chunk index*/
	stream_status status;/*stream status:0-close,1-active 2-pause*/

	uint8_t  *pWriteBuf;/*data write buf*/
	size_t   writeOffset; /*data write offset*/

	/*
	*data clip
	*/
	int     file_index;/*current file index*/
	int     hFile; /*current file handle*/
	size_t  file_Length;/*current file length*/
	uint16_t cur_year;/*year*/
	uint8_t	 cur_month;/*month,1~12*/
	uint8_t	 cur_day;/*day ,1~31*/

	pchunk header;
	pchunk tail;

	smart_lock *plock;

	data_stream()
	{
		streamid = 0;
		fmt = 0;
		current_index = 0;
		status = DS_CLOSE;

		pWriteBuf = NULL;
		writeOffset = 0;

		hFile = INVALID_HANDLE_VALUE;
        file_index = 0;
		file_Length = 0;
		cur_year = 0;
		cur_month = 0;
		cur_day = 0;

		header = NULL;
		tail = header;

		plock = new smart_lock();
	}
};

typedef data_stream *  pStream;

/**
 * DataStream manage class
 */
class DataStream {
public:
	DataStream();
	virtual ~DataStream();

	/*
	*init data stream buf
	*/
	int init_avchunk(uint16_t max_stream_count,bool is_clip = false,const char * root = NULL);

	/*
	* init data stream,to write chunk or packet chunk
	* streamid: data stream id
	* fmt: data fmt
	*/
	bool init_data_stream(uint16_t streamid,uint8_t fmt,uint8_t * pArgData,size_t len);

	/*
	* wiret chunk data,by chunk trans protocal
	* pData: chunk data
	* size: write data size
	* streamid: chunk data stream id
	*/
	bool write_chunk (uint16_t streamid,uint8_t * pData,size_t size);
	/*
	* read chunk data,by chunk trans protocal
	* pBuf: read buf
	* buf_len: max read length
	* uIndex: read index
	* uoffset: read index chunk data offset
	* return read len to read_len
	* streamid: chunk data stream id
	* flag:read chunk ,1 is first flag
	*/
	bool read_chunk(uint8_t * pBuf,size_t buf_len,uint16_t streamid,uint64_t  &uIndex,ulong &uoffset,uint64_t &read_len,BOOL flag);


	/*
	*get current data strema info
	*set index,and offset
	* if stream not found ,return false,else return true
	*/
	bool get_current_data_stream_index(uint16_t streamid,uint64_t  &uIndex,ulong &uoffset);


	/*
	*get current data stream time info
	*/
	bool get_current_data_stream_timeinfo(uint16_t streamid,token_ex * pTokenEx);


	/*
	*get next data clip
	*/
	int get_next_data_clip(uint16_t streamid,int fmt,token_ex * ptoken,const char * root,uint64_t & hFile_offset,uint64_t & hFile_size,int & open_flag);


	/*
	* close_data_stream
	* flag: TRUE,free stream
	* flag: FALSE,pause write stream
	*/
	bool close_data_stream(uint16_t streamid,int flag);
	/*
	*chunk count
	*/
	int get_free_chunk_count(void);
	int get_current_chunk_count(void);
	/*
	*data stream count
	*/
	int get_free_data_stream_count(void);
	int get_current_data_stream_count(void);
protected:
	void alloc_data_stream(pStream & pAVStream);
	void free_data_stream(pStream  pAVStream);
	void free_limit_data_chunk(pStream  pAVstream);
	/*
	* packet source data to chunk
	* streamid: data stream id
	* fmt: data fmt
	* pdata,source data
	* len: data length
	*/
	bool packet_chunk(uint16_t streamid,uint8_t * pSrcData,size_t len);

	/*
	*packet stream
	*/
	virtual bool chunk_init_stream(uint16_t stream_id,uint8_t fmt);
	virtual bool chunk_write_stream(uint16_t stream_id,char * buf,u_long len);
	virtual bool chunk_close_stream(uint16_t stream_id);
	virtual	int  chunk_log(int nloglvl,const char * lpszFormat, ...);
protected:
	/*
	*save data to clip file
	*/
	bool save_clip_data(pStream pAVstream,chunk * pCk);
private:
	bool init_flag;
	/*
	*chunk memory
	*/
	chunk_buf chunk_mem;
	/*
	* data stream
	*/
	data_stream ** avlist;
	int list_size;
	smart_lock list_lock;

	/*
	*free data stream
	*/
	stack<data_stream *> free_list;
	smart_lock free_lock;

	/*
	*chunk max cach count
	*/
	int limit_count;

	/*
	*is save data clip
	*/
	bool is_save_clip;

	/*
	*save root path
	*/
	char rootpath[FILE_MAX_PATH];
};

#endif /* DATASTREAM_H_ */
